﻿$(function () { // DOM ready
	console.log("Start");
	
	Game.initEvent();

	// wait until every image is loaded to launch the game
	loadimages(images, function () {
		Game.init();
	});
});

/********* Object Game  ***************/
var Game = Object();

// Constants
Game.ROW_NUMBER = 8;	// Số dòng quân cờ
Game.COLUMN_NUMBER = 8;	// Số cột quân cờ
Game.ITEM_NUMBER = 6;	// Số lượng quân cờ khác nhau (độ khó)

// Properties
Game.itemList = [];		// List các quân cờ trong bàn cờ


//constants
var TAILLE_ICONE = 80;

//variables
var hint_mode = false;
var best_score = 0;
var score = 0;
var best_combo = 0;
var combo = 0;
var doigt_init_x = 0;
var doigt_init_y = 0;
var $touched_item;		// Quân cờ đang được touch
var $moved_item;		// Quân cờ bị moved
var is_item_touching = false;
var is_item_moving = false;
var hint_timeout;		// Biến timeout dùng cho hint

var tmp_item_list = [];			// Bản sao của Game.itemList, đánh dấu những quân đã bị ăn và chưa bị ăn
var tmp_check_horizontal = [];	// Mảng 2 chiếu chứa giá trị true, false dùng để check quân nào được ăn theo hàng ngang
var tmp_check_vertical = [];	// Mảng 2 chiếu chứa giá trị true, false dùng để check quân nào được ăn theo hàng ngang
var tab_test = [];				// Mảng data dùng để check quân cờ có thể move hay không

var images = [
	'images/icones/sprite.png',
    'images/picto/fire.gif',
    'images/picto/star.gif',
];

/*
 * Init event touch or click item
 */
Game.initEvent = function(){
	console.log("Init event");
	
	var is_dragmove = false;
	var row_index = 0;
	var column_index = 0;
	
	$('.icone').live('dragstart', function (e) {	// prevent image dragging
		e.preventDefault();
	});

	$('#zone_message').live('touchmove mousemove', function (e) {	// prevent window scrolling
	    e.preventDefault();
	});
	
	// xác định quân cờ có đang đc touch thông qua biến: is_item_touching
	$('.icone').live('touchstart mousedown', function (e) {
		
		console.log("touch quân cờ");
		if (!is_item_touching && !is_item_moving) {
			is_dragmove = false;
			$touched_item = $(this);
			$touched_item.css('z-index', 20);
			row_index = Number($touched_item.attr('data-row'));
			column_index = Number($touched_item.attr('data-col'));
			
			if (e.originalEvent.type == 'touchstart') {
				doigt_init_x = e.originalEvent.touches[0].clientX;
				doigt_init_y = e.originalEvent.touches[0].clientY;
			}
			
			if (e.originalEvent.type == 'mousedown') {
				doigt_init_x = e.originalEvent.clientX;
				doigt_init_y = e.originalEvent.clientY;
			}
			
			is_item_touching = true;
	    }
	});
	  
	// Xác định vị trí của con trỏ chuột
	$('#zone_jeu').live('touchmove mousemove', function (e) {
	    e.preventDefault();			// prevent window scrolling
		
		//console.log("Move vào bàn cờ");
	    if (is_item_touching) {
	    	var distance_x, distance_y;

	    	if (e.originalEvent.type == 'touchmove') {
	    		distance_x = e.originalEvent.touches[0].clientX - doigt_init_x;
	    		distance_y = e.originalEvent.touches[0].clientY - doigt_init_y;
	    	}
	    	
	    	if (e.originalEvent.type == 'mousemove') {
	    		distance_x = e.originalEvent.clientX - doigt_init_x;
	    		distance_y = e.originalEvent.clientY - doigt_init_y;
	    	}

	    	if (Math.abs(distance_x) > Math.abs(distance_y)) {
	    		if (distance_x > TAILLE_ICONE / 2) {
	    			// right
	    			if (column_index < Game.COLUMN_NUMBER - 1) {
	    				is_dragmove = true;
	    				$('.icone').removeClass('click adjacent');
	    				Game.moveItem(row_index, column_index, row_index, column_index + 1);
	    			}
	    		}

	    		if (distance_x < -TAILLE_ICONE / 2) {
	    			// left
	    			if (column_index > 0) {
	    				is_dragmove = true;
	    				$('.icone').removeClass('click adjacent');
	    				Game.moveItem(row_index, column_index, row_index, column_index - 1);
	    			}
	    		}
	    	} 
	    	else 
	    	{
	    		if (distance_y > TAILLE_ICONE / 2) {
	    			// down
	    			if (row_index < Game.ROW_NUMBER - 1) {
	    				is_dragmove = true;
	    				$('.icone').removeClass('click adjacent');
	    				Game.moveItem(row_index, column_index, row_index + 1, column_index);
	    			}
	    		}

	    		if (distance_y < -TAILLE_ICONE / 2) {
	    			// up
	    			if (row_index > 0) {
	    				is_dragmove = true;
	    				$('.icone').removeClass('click adjacent');
	    				Game.moveItem(row_index, column_index, row_index - 1, column_index);
	    			}
	    		}
	    	}
	    }
	  });
	  
	  // Khi nhả chuột
	  $('#zone_jeu').live('touchend mouseup', function (e) {
		  if (is_item_touching) {
			  is_item_touching = false;
			  $touched_item.css('z-index', 10);
			  
			  if(!is_dragmove){
		        verify_click($touched_item);
		      }
		  }
	  });
}

Game.init = function() {
	console.log("After load all images, Game.init()");
	
	$('#zone_message').html('');

	score = 0;
	combo = 0;
	Game.ITEM_NUMBER = 6; // normal : 6

	Game.itemList = [];

	clearTimeout(hint_timeout);
	$('.hint').removeClass('hint');
	hint_mode = false;

	Game.createNew("zone_jeu");
};

/*
 * Tạo UI cho bàn cờ
 */
Game.createNew = function(containerID){
	console.log("Get data random bàn cờ from Server");
	Game.itemList = Server.createRandomData();
	
	console.log("data: ", Game.itemList);
	
	var content = "";
	var item = null;
  	
	for (var i = 0 ; i < Game.ROW_NUMBER ; i++) {		  
		for (var j = 0 ; j < Game.COLUMN_NUMBER ; j++) {
			item = Game.itemList[i][j];
	      
			content += '<div class="icone icone_' + item + '" data-row="' + i + '" data-col="' + j + '" data-icone="' + item + '" style="top: ' + Number(i*TAILLE_ICONE) + 'px; left: ' + Number(j*TAILLE_ICONE) + 'px;"></div>';
		}
	}  
  
	// Render những div quân cờ vào id "zone_jeu"
	$('#' + containerID).html(content);
	
	console.log("Finish create bàn cờ");
}

/*
 * Di chuyển quân cờ
 */
Game.moveItem = function(row, column, new_row, new_column) {
	
	// Animation move
	console.log("Move (" + row + ", " + column + ") -> (" + new_row + "," + new_column + ")");
	
	is_item_touching = false;
	is_item_moving = true;
	
	clearTimeout(hint_timeout);
	$('.hint').removeClass('hint');
	hint_mode = false;
	
	$moved_item = $('.icone[data-row=' + new_row + '][data-col=' + new_column + ']');

	$touched_item.css('z-index', 10);

	// Switch item positions
	var item = Game.itemList[row][column];
	var new_item = Game.itemList[new_row][new_column];

	$touched_item.attr('data-row', new_row);
	$touched_item.attr('data-col', new_column);
	$moved_item.attr('data-row', row);
	$moved_item.attr('data-col', column);

	$touched_item.css({
		'left': new_column*TAILLE_ICONE,
		'top': new_row*TAILLE_ICONE
	});
  
	$moved_item.css({
		'left': column*TAILLE_ICONE,
		'top': row*TAILLE_ICONE
	});

  Game.itemList[row][column] = new_item;
  Game.itemList[new_row][new_column] = item;
  /*********/

  setTimeout(function () {
	  var result = Server.moveItem(row, column, new_row, new_column);
	  
	  if(result.status){	  // Sau khi di chuyển, kiểm tra có ăn hay ko
		  
		  animation_finish_items(result.tmpItemList);	// Animation ăn item
		  
		  setTimeout(function () {
			  
			  add_new_item(result.itemList);	// Lấp đầy những quân bị ăn
				
			  setTimeout(function () {
				  check_all_item();
			  }, 400);
		  }, 400);
	  }
	  else
	  {	
		// Revert lại vị trí 2 quân cờ nếu ko ăn
		  $touched_item.attr('data-row', row);
		  $touched_item.attr('data-col', column);
		  $moved_item.attr('data-row', new_row);
		  $moved_item.attr('data-col', new_column);

		  $touched_item.css({
			  'left': column * TAILLE_ICONE,
			  'top': row * TAILLE_ICONE
		  });
		  
		  $moved_item.css({
			  'left': new_column*TAILLE_ICONE,
			  'top': new_row*TAILLE_ICONE
		  });

		  Game.itemList[row][column] = item;
		  Game.itemList[new_row][new_column] = new_item;
		  
		  is_item_moving = false;
		  
		  Game.showHint();
	  }

	  $touched_item = undefined;
	  $moved_item = undefined;

  	}, 300);
};

Game.showHint = function(){
	// Display hint after a few seconds
	
	hint_timeout = setTimeout(function () {
		hint_mode = true;
		test_possible_move();
    }, 5000);
}

/*
 * Check all item
 */
function check_all_item(){

	var result = Server.checkAllItems();
  
	if(result.status)	// Sau khi di chuyển, kiểm tra có ăn hay ko
	{	  	
		animation_finish_items(result.tmpItemList);
		  
		setTimeout(function () {
			add_new_item(result.itemList);	// Lấp đầy những quân bị ăn
			setTimeout(function () {
				check_all_item();
			}, 400);
		}, 400);
	}
	else
	{
		is_item_moving = false;
		
		Game.showHint();
	}
}


function animation_finish_items(item_list){
	// Remove những quân đã bị ăn
	for (var i = 0; i < Game.ROW_NUMBER; i++) {
		for (var j = 0 ; j < Game.COLUMN_NUMBER; j++) {
			if (item_list[i][j]) {          
				Game.itemList[i][j] = 0;
				$('.icone[data-row=' + i + '][data-col=' + j + ']').fadeOut(300, function () { $(this).remove(); });	// Animation remove quân cờ
		  
				// Hiển thị điểm được ăn trên đừng con cờ
				var points = 10;
				var $aff_score = $('<div class="aff_score" style="left:' + j*TAILLE_ICONE + 'px; top:' + i*TAILLE_ICONE + 'px;">+' + points + '</div>');
				$('#zone_jeu').append($aff_score);
				score += points;
			}          
		}
	}

	$('#current_score_num').html(score);

	setTimeout(function () {
		$aff_score.fadeOut(400, function () { $('.aff_score').remove(); });
		$('#zone_message').html('');
	}, 700);

}

/*
 * Tạo ra những quân cờ mới thay thế cho những quân cờ đã bị ăn
 */
function add_new_item(new_item_list) {
	
	for (var i = Game.ROW_NUMBER-1; i >= 0 ; i--) {
		for (var j = 0 ; j < Game.COLUMN_NUMBER; j++) {

			if (Game.itemList[i][j] == 0) {
				// look above for an icon to fill the hole
				var k = 1;
				while((i - k) >= 0 && Game.itemList[i-k][j] == 0) {
					k++;
				}

				if ((i - k) < 0) {  // Random quân tại vị trí trống	
					// no icon found above : create random new icon
					var random_item = new_item_list[i][j];
					
					$new_icon = $('<div class="icone icone_' + random_item + '" data-row="' + i + '" data-col="' + j + '" data-icone="' + random_item + '"></div>');
					$new_icon.css({
						'left': j*TAILLE_ICONE,
						'top': -TAILLE_ICONE
					});
				  
					$('#zone_jeu').append($new_icon);
          
					$new_icon.animate({	// Animation rớt từ trên xuống ô trống
						'top': i*TAILLE_ICONE
					}, 0);
          
					Game.itemList[i][j] = random_item;
				} 
				else 	// Chuyển quân trên xuống quân dưới
				{
					// icon found above : icon falling animation
					var $icone_chute = $('.icone[data-row=' + (i - k) + '][data-col=' + j + ']');
					// update icon properties (correct line and column numbers)
					$icone_chute.attr('data-row', i);
					$icone_chute.css('top', i*TAILLE_ICONE);

					Game.itemList[i][j] = Game.itemList[i-k][j];
					Game.itemList[i-k][j] = 0;
				}
			}
		}
  	}
};

/*
 * Hiển thị những quân xung quanh có thể move xung quanh quân được click (hoặc move nếu click những quân có thể move)
 */
function verify_click($icone_test) {
	var row = 0;
	var column = 0;
	
	if(!$('.icone.click').length)	// Click lần đầu
	{
		console.log("Click lần đầu");
		
		$icone_test.addClass('click');
		new_row = Number($icone_test.attr('data-row'));
		new_column = Number($icone_test.attr('data-col'));
		add_adjacent(new_row, new_column);
	} 
	else 	// Click những lần sau
	{
		console.log("Click lần sau");
	
		$icone_ref = $('.icone.click');
		row = Number($icone_ref.attr('data-row'));
		column = Number($icone_ref.attr('data-col'));
		new_row = Number($icone_test.attr('data-row'));
		new_column = Number($icone_test.attr('data-col'));
		
		// Nếu click những vùng đang chọn, click sẽ move quân cờ
		if ((row == new_row && column == new_column - 1) ||
		  (row == new_row && column == new_column + 1) ||
		  (row == new_row - 1 && column == new_column) ||
		  (row == new_row + 1 && column == new_column) ) 
		{
			$touched_item = $icone_ref;
			Game.moveItem(row, column, new_row, new_column);
			$('.icone').removeClass('click adjacent');
		} 
		else // Click sang những vùng khác, sẽ show những nước đi có thể xung quanh quân được chọn
		{
			$('.icone').removeClass('click adjacent');
			$icone_test.addClass('click');
			add_adjacent(new_row, new_column);
		}
	}
};

/*
 * Hiển thị trạng thái là quân có thể move xung quanh quân cờ được click
 */
function add_adjacent(row, column) {
	if (row > 0) {
		$('.icone[data-row=' + (row-1) + '][data-col=' + column + ']').addClass('adjacent');
	}
	
	if (column > 0) {
		$('.icone[data-row=' + row + '][data-col=' + (column-1) + ']').addClass('adjacent');
	}
	
	if (column < Game.COLUMN_NUMBER-1) {
		$('.icone[data-row=' + row + '][data-col=' + (column+1) + ']').addClass('adjacent');
	}
  
	if (row < Game.ROW_NUMBER-1) {
		$('.icone[data-row=' + (row+1) + '][data-col=' + column + ']').addClass('adjacent');
	}
}

/*
 * Kiểm tra có nước cờ nào có thể move trên cả bàn cờ hay không
 * Return:
 * 		- true : có thể move
 * 		- false: không thể move
 */
function test_possible_move() { 
	var move_found = false;
	var hint_displayed = false;
	var nb_possible_moves = 0;

	for (var i = 0; i < Game.ROW_NUMBER; i++) {
		tab_test[i] = [];
    	for (var j = 0 ; j < Game.COLUMN_NUMBER; j++) {
    		tab_test[i][j] = Game.itemList[i][j];
	    }
	}

	for (var i = 0; i < Game.ROW_NUMBER; i++) {
	    for (var j = 0 ; j < Game.COLUMN_NUMBER; j++) {
	      // test right move
	    	if (j < Game.COLUMN_NUMBER-1) {
	    		tab_test[i][j] = Game.itemList[i][j+1];
	    		tab_test[i][j+1] = Game.itemList[i][j];
	    		
	    		if (test_chain_game_over(i, j)) {
	    			move_found = true;
	    			nb_possible_moves++;
	    			
	    			if(debug_mode){
	    				$('.icone[data-row=' + i + '][data-col=' + (j+1) + ']').addClass('hint');
	    			}
	    			
	    			if (hint_mode && !hint_displayed) {
	    				$('.icone[data-row=' + i + '][data-col=' + (j+1) + ']').addClass('hint');
	    				hint_displayed = true;
	    			}
	    		}
	        
	    		if (test_chain_game_over(i, j+1)) {
	    			move_found = true;
	    			nb_possible_moves++;
	    			if(debug_mode){
	    				$('.icone[data-row=' + i + '][data-col=' + j + ']').addClass('hint');
	    			}
	    			
	    			if (hint_mode && !hint_displayed) {
	    				$('.icone[data-row=' + i + '][data-col=' + j + ']').addClass('hint');
	    				hint_displayed = true;
	    			}
	    		}
	        
	    		tab_test[i][j] = Game.itemList[i][j];
	    		tab_test[i][j+1] = Game.itemList[i][j+1];
	    	}

	    	// test down move
	    	if (i < Game.ROW_NUMBER-1) {
	    		tab_test[i][j] = Game.itemList[i+1][j];
	    		tab_test[i+1][j] = Game.itemList[i][j];
	    		if (test_chain_game_over(i, j)) {
	    			move_found = true;
	    			nb_possible_moves++;
	    			if(debug_mode){
	    				$('.icone[data-row=' + (i+1) + '][data-col=' + j + ']').addClass('hint');
	    			}
	    			
	    			if (hint_mode && !hint_displayed) {
	    				$('.icone[data-row=' + (i+1) + '][data-col=' + j + ']').addClass('hint');
	    				hint_displayed = true;
	    			}
	    		}
	        
	    		if (test_chain_game_over(i+1, j)) {
	    			move_found = true;
	    			nb_possible_moves++;
	    			
	    			if(debug_mode){
	    				$('.icone[data-row=' + i + '][data-col=' + j + ']').addClass('hint');
	    			}
	    			
	    			if (hint_mode && !hint_displayed) {
	    				$('.icone[data-row=' + i + '][data-col=' + j + ']').addClass('hint');
	    				hint_displayed = true;
	    			}
	    		}
	    		
	    		tab_test[i][j] = Game.itemList[i][j];
	    		tab_test[i+1][j] = Game.itemList[i+1][j];
	    	}
    	}
	}

	if(nb_possible_moves <= 3) {
	    if(nb_possible_moves <= 1) {
	    	$('#moves').addClass('critical').html(nb_possible_moves + '<br>move');
	    } else {
	    	$('#moves').removeClass('critical').html(nb_possible_moves + '<br>moves');
	    }
	} 
	else 
	{
	    $('#moves').removeClass('critical').html('');
	}
	  
	return move_found;
};

// Kiểm tra item(row, column) có thể ăn hay không (dùng để hint)	
function test_chain_game_over(row, column) {
	var result = false;
	var item_value = tab_test[row][column];
	var vertical_number = 1;
	var horizontal_number = 1;
	
	var i;
	// up
	i = 1;
	while(row-i >= 0 && tab_test[row-i][column] == item_value) {
	    vertical_number++;
	    i++;
	}

	// down
	i = 1;
	while(row+i < Game.COLUMN_NUMBER && tab_test[row+i][column] == item_value) {
	    vertical_number++;
	    i++;
	}
	
	// left
	i = 1;
	while(column-i >= 0 && tab_test[row][column-i] == item_value) {
		horizontal_number++;
		i++;
	}

	// right
	i = 1;
	while(column+i < Game.ROW_NUMBER && tab_test[row][column+i] == item_value) {
	    horizontal_number++;
	    i++;
	}
	
	if (vertical_number >= 3) {
	    result = true;
	}
	if (horizontal_number >= 3) {
	    result = true;
	}
	if (tab_test[row][column] == 10) {
	    // hypercube
	    result = true;
	}
	
	return result;
};
	
/* 
 * Load images
 */
function loadimages(imgArr,callback) {
  //Keep track of the images that are loaded
  var imagesLoaded = 0;
  function _loadAllImages(callback) {
    //Create an temp image and load the url
    var img = new Image();
    $(img).attr('src',imgArr[imagesLoaded]);
    if (img.complete || img.readyState === 4) {
      // image is cached
      imagesLoaded++;
      //Check if all images are loaded
      if (imagesLoaded == imgArr.length) {
        //If all images loaded do the callback
        callback();
      } else {
        //If not all images are loaded call own function again
        _loadAllImages(callback);
      }
    } else {
      $(img).load(function () {
        //Increment the images loaded variable
        imagesLoaded++;
        //Check if all images are loaded
        if (imagesLoaded == imgArr.length) {
          //If all images loaded do the callback
          callback();
        } else {
          //If not all images are loaded call own function again
          _loadAllImages(callback);
        }
      });
    }
  };    
  
  _loadAllImages(callback);
}
